#pragma once

#define ParserString(KEY)         \
  if (input[#KEY].isString()) {   \
    KEY = input[#KEY].asString(); \
  }
#define ParserInt(KEY)         \
  if (input[#KEY].isInt()) {   \
    KEY = input[#KEY].asInt(); \
  }
#define ParserBool(KEY)         \
  if (input[#KEY].isBool()) {   \
    KEY = input[#KEY].asBool(); \
  }
#define ParserStruct(KEY)       \
  if (input[#KEY].isObject()) { \
    KEY.Parser(input[#KEY]);    \
  }
#define ParserArray(KEY, VALUE)                                             \
  if (input[#KEY].isArray()) {                                              \
    Json::Value& pages = input[#KEY];                                       \
    for (Json::ValueIterator it = pages.begin(); it != pages.end(); ++it) { \
      VALUE unit;                                                           \
      unit.Parser(*it);                                                     \
      KEY.push_back(unit);                                                  \
    }                                                                       \
  }
#define ParserArrayInt(KEY)                                                 \
  if (input[#KEY].isArray()) {                                              \
    Json::Value& pages = input[#KEY];                                       \
    for (Json::ValueIterator it = pages.begin(); it != pages.end(); ++it) { \
      const Json::Value& jsValue = *it;                                     \
      if (jsValue.isInt()) KEY.push_back(jsValue.asInt());                  \
    }                                                                       \
  }

#define WrapperBegin() Json::Value result;
#define WrapperValue(KEY) result[#KEY] = Json::Value(KEY);
#define WrapperStruct(KEY) result[#KEY] = KEY.Wrapper();
#define WrapperArray(KEY)              \
  Json::Value names(Json::arrayValue); \
  for (auto it : KEY) {                \
    names.append(it.Wrapper());        \
  }                                    \
  result[#KEY] = names;

#define WrapperArrayInt(KEY)           \
  Json::Value names(Json::arrayValue); \
  for (auto it : KEY) {                \
    names.append(Json::Value(it));     \
  }                                    \
  result[#KEY] = names;

#define WrapperMap(KEY)                \
  Json::Value names(Json::arrayValue); \
  for (auto it : KEY) {                \
    names.append(it.second.Wrapper()); \
  }                                    \
  result[#KEY] = names;

#define WrapperEnd() return result;
